﻿using System.IO.Hashing;
using System.Text;

namespace tools.algorithm
{
    /// <summary>
    /// XXHash 工具类（非安全哈希算法）
    /// </summary>
    public static class XxHashTool
    {
        /// <summary>
        /// 使用 XXHash 64 算法计算字符串的哈希值
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>20 位左右无符号长整型数值</returns>
        public static ulong Get64(string? str)
        {
            ArgumentException.ThrowIfNullOrWhiteSpace(str);

            byte[] data = Encoding.UTF8.GetBytes(str);
            return XxHash64.HashToUInt64(data);
        }

        /// <summary>
        /// 使用 XXHash 128 算法计算字符串的哈希值
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>40 位左右无符号长整型数值</returns>
        public static UInt128 Get128(string? str)
        {
            ArgumentException.ThrowIfNullOrWhiteSpace(str);

            byte[] data = Encoding.UTF8.GetBytes(str);
            return XxHash128.HashToUInt128(data);
        }

        /// <summary>
        /// 使用 XXHash 64 算法计算文件流的哈希值
        /// </summary>
        /// <param name="stream">文件流</param>
        /// <returns>20 位左右无符号长整型数值</returns>
        public static ulong Get64(Stream? stream)
        {
            ArgumentNullException.ThrowIfNull(stream);
            stream.Position = 0;

            var xxHash = new XxHash64();
            xxHash.Append(stream);
            return xxHash.GetCurrentHashAsUInt64();
        }

        /// <summary>
        /// 使用 XXHash 128 算法计算文件流的哈希值
        /// </summary>
        /// <param name="stream">文件流</param>
        /// <returns>40 位左右无符号长整型数值</returns>
        public static UInt128 Get128(Stream? stream)
        {
            ArgumentNullException.ThrowIfNull(stream);
            stream.Position = 0;

            var xxHash = new XxHash128();
            xxHash.Append(stream);
            return xxHash.GetCurrentHashAsUInt128();
        }
    }
}
